home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr13 / aurora2c.zip / EXT.AML < prev    next >
Text File  |  1995-04-07  |  73KB  |  2,801 lines

  1.  
  2. // ───────────────────────────────────────────────────────────────────
  3. // The Aurora Editor v2.0
  4. // Copyright 1993-1995 nuText Systems. All Rights Reserved Worldwide.
  5. //
  6. // Editor library extensions (included by MAIN.AML)
  7. //
  8. // *You should be very familiar with AML before making changes here*
  9. // If you have made any changes, save this file and select 'Recompile
  10. // the Editor' <alt f2> from the Set menu. Exit and re-enter the
  11. // editor for your changes to take effect.
  12. // ───────────────────────────────────────────────────────────────────
  13.  
  14. // ───────────────────────────────────────────────────────────────────
  15. //  All windows
  16. // ───────────────────────────────────────────────────────────────────
  17.  
  18.   object  a
  19.  
  20.     // get the drive and path portion of a filespec
  21.     function  getpath (file)
  22.       return  file [1 : pos "\\" file 'r']
  23.     end
  24.  
  25.     // get the name and extension portion of a filespec
  26.     function  getname (file)
  27.       return  file [(pos "\\" file 'r') + 1 : 0]
  28.     end
  29.  
  30.     // get the extension portion of a filespec
  31.     function  getext (file)
  32.       p = pos '.' file 'r'
  33.       if? p file [p : TO_END] ''
  34.     end
  35.  
  36.     // append a default extension for filenames that don't have one
  37.     function  defext (file extension)
  38.       if pos '.' file then
  39.         file
  40.       else
  41.         file + '.' + extension
  42.       end
  43.     end
  44.  
  45.     // force a filename to have an extension
  46.     function  forceext (file ext)
  47.       p = pos '.' file 'r'
  48.       return (if? p  file [1 : p]  file + '.') + ext
  49.     end
  50.  
  51.     // generate <shiftdown>, <shiftup> events from raw <shiftkey> event
  52.     function  <shiftkey> (newstate oldstate)
  53.       send ( if newstate & 3 and not (oldstate & 3) then
  54.                "shiftdown"
  55.              elseif oldstate & 3 and not (newstate & 3) then
  56.                "shiftup"
  57.              end )
  58.     end
  59.  
  60.     // generate multi-key events
  61.     function  prefix (keycode)
  62.       keyname = locase (getkeyname keycode)
  63.       say  keyname + "<more...>"
  64.       keyname2 = locase (getkeyname (getkey))
  65.       queue  keyname + keyname2
  66.       // allow the <ctrl> key to be held down...
  67.       if keyname [1:5] == "<ctrl" and keyname2 [1:5] == "<ctrl" then
  68.         queue keyname + '<' + keyname2 [7 : TO_END]
  69.       end
  70.       display
  71.     end
  72.  
  73.     // repeat keys for a user-specified number of times
  74.     function  askrepkey
  75.       var keystring
  76.       var i
  77.       say "Enter keys to repeat, then <esc>:"
  78.       hidecursor
  79.       keycode = getkey
  80.       while keycode <> <esc> do
  81.         keystring = keystring + (char2 keycode)
  82.         keycode = getkey
  83.       end
  84.       if keystring then
  85.         count = ask "Number of repetitions"
  86.         if count then
  87.           strlen = sizeof keystring
  88.           while count do
  89.             j = 1
  90.             while j < strlen do
  91.               queuekey (bin2int keystring [j : 2])
  92.               j = j + 2
  93.             end
  94.             repeat
  95.               dispatch
  96.             until not event?
  97.             count = count - 1
  98.           end
  99.         end
  100.       end
  101.     end
  102.  
  103.     // a simple file picklist
  104.     function  picklist (filespec title)
  105.       filespec = qualify filespec (getbufname)
  106.       repeat
  107.         filespec = askfile filespec  filespec + title _FmgrSort _FmgrOpt
  108.       until not (filespec and (dir? filespec))
  109.       return filespec
  110.     end
  111.  
  112.     // execute a fully qualified DOS program
  113.     // (saving and restoring the current path)
  114.     function  os (program options)
  115.       cp = getcurrpath
  116.       currpath (getpath (getbufname))
  117.       r = exec program options
  118.       currpath cp
  119.       return r
  120.     end
  121.  
  122.     // shell to DOS by executing COMMAND.COM
  123.     function  shell
  124.       os (getenv "COMSPEC") "ch"
  125.     end
  126.  
  127.     // execute DOS commands, programs, and .bat files
  128.     function  run (file options)
  129.       if file then
  130.         os (getenv "COMSPEC") + " /c " + file  options
  131.       else
  132.         shell
  133.       end
  134.     end
  135.  
  136.     // execute DOS commands or programs and capture the output
  137.     // via DOS piping (will not capture .bat file output)
  138.     function  runcap (command options)
  139.       _cap = _cap + 1
  140.       capfile = qualify  "capture." + _cap  (getbufname)
  141.       run  command + '>' + capfile  options
  142.       open capfile
  143.       deletefile capfile
  144.     end
  145.  
  146.     // translate an AML compiler error code to an error message
  147.     function  errormsg (error)
  148.       case error
  149.         when 1001  "Can't open file"
  150.         when 1002, 1003  "Read error"
  151.         when 1004  "Not an executable macro file"
  152.         when 1031  "Write error"
  153.         when 1032  "Can't open compiler output file"
  154.         when 1101  "No closing quote"
  155.         when 1102  "No closing bracket"
  156.         when 1103  "Invalid symbol"
  157.         when 1104  "Invalid key or event"
  158.         when 1301  "No terminator"
  159.         when 1302  "Unexpected end of source"
  160.         when 1303  "No closing parenthesis"
  161.         when 1310  "Unexpected argument"
  162.         when 1311  "Unexpected terminator"
  163.         when 1312  "Unexpected function"
  164.         when 1313  "Unexpected operator"
  165.         when 1319  "Identifier '" + (geterror 's') + "' not defined"
  166.         when 1320  "Bad assignment"
  167.         when 1330  "Bad when clause"
  168.         when 1336  "Improperly placed break"
  169.         when 1337  "Invalid reference"
  170.         when 1501  "Can't open include file " + (geterror 's')
  171.         when 1502  "Include level exceeded"
  172.         when 1503  "Can't include compiled file in expression"
  173.         when 1504  "Include must be at top level"
  174.         when 1505  "Define can't be nested"
  175.         when 1506  "Function must be at top level"
  176.         when 1507  "Can't redefine builtin function"
  177.         when 1508  "Duplicated function argument"
  178.         when 1509  "Object statement not permitted"
  179.         when 1701  "Too many variables"
  180.         when 1702  "Too many function arguments"
  181.         when 1703  "Function or expression too large"
  182.         when 1704, 1705, 1707   "Internal stack overflow"
  183.         when 1706  "Out of symbol space"
  184.         otherwise "Fatal compilation error " + error
  185.       end
  186.     end
  187.  
  188.     // compile a macro with error messages
  189.     // the cursor is moved to any syntax errors
  190.     function  compilemacro2 (source dest msg)
  191.       if not source then
  192.         source = getbufname
  193.       end
  194.       say (if? msg msg "Compiling...")
  195.       source = qualify (defext source "aml") (getbufname)
  196.       error = compilemacro source (if? dest dest (forceext source 'x'))
  197.  
  198.       if error then
  199.  
  200.         // get additional error info
  201.         column = geterror 'k'
  202.         line = geterror 'l'
  203.         file = geterror 'f'
  204.  
  205.         // translate error code to an error message
  206.         msg = errormsg error
  207.  
  208.         // position the cursor to the error
  209.         if error <> 1001 and (open file) then
  210.           gotopos column line
  211.           send "onfound"
  212.         end
  213.  
  214.         // display the error
  215.         msgbox  file + " (line " + line + ", col " + column + "): " + msg
  216.                 "Error!" 'b'
  217.       else
  218.         say "Done."
  219.       end
  220.  
  221.       return error
  222.     end
  223.  
  224.     // regenerate the editor boot macro (a.x)
  225.     function  regen (msg)
  226.       dest = bootpath "main.x"
  227.       error = compilemacro2 (bootpath "main.aml") dest msg
  228.       if not error then
  229.         bootfile = bootpath "a.x"
  230.         deletefile bootfile
  231.         renamefile dest bootfile
  232.       end
  233.       return error
  234.     end
  235.  
  236.     // regenerate the editor boot macro (a.x) with a message
  237.     function  recompile
  238.       if not regen then
  239.         msgbox "Exit and re-enter for changes to take effect. "
  240.       end
  241.     end
  242.  
  243.     // regenerate the editor boot macro (a.x) with a message,
  244.     // and integrate current config variables in compilation
  245.     function  saveconfig
  246.       configx = bootpath "config.x"
  247.       saveobject "prf" configx
  248.       regen "Saving..."
  249.       deletefile configx
  250.     end
  251.  
  252.     // load and run a compiled macro file
  253.     function  includemacro2 (macrofile)
  254.       includemacro (qualify (forceext
  255.                  (if? macrofile macrofile (getbufname)) 'x') (getbufname))
  256.     end
  257.  
  258.     // load, run, and discard a compiled macro file
  259.     function  runmacro2 (macrofile)
  260.       runmacro (qualify (forceext
  261.                  (if? macrofile macrofile (getbufname)) 'x') (getbufname))
  262.     end
  263.  
  264.     // send a string to the default printer device
  265.     function  printstr (string)
  266.       if string then
  267.         fileid = openfile _PrtDev 'w'
  268.         if fileid then
  269.           writefile fileid string
  270.           closefile fileid
  271.         end
  272.       end
  273.     end
  274.  
  275.     // open a new file
  276.     function  opennew (file options)
  277.       prevbufname = getbufname
  278.       buffer = createbuf
  279.       if buffer then
  280.         setbufname (qualify (if? file file "NEW.TXT") prevbufname)
  281.         openbuf buffer options
  282.       end
  283.     end
  284.  
  285.     // toggle the video mode between 80x25 and 80x50
  286.     function  togglemode
  287.       videomode 80 (if? getvidrows == 25  50 25)
  288.     end
  289.  
  290.  
  291.     // search/replace with verification
  292.     // (returns the number of replacements made)
  293.     function  replver (searchstr replstr options)
  294.  
  295.       var title
  296.       var count
  297.  
  298.       repeat
  299.         length = find searchstr options
  300.         if length then
  301.  
  302.           if not title then
  303.             title = gettitle
  304.             settitle  "Replace (Yes/No/All/One/Reverse/Undo/Quit)? "
  305.             // remove global for next find
  306.             options = sub 'g' '' options
  307.           end
  308.  
  309.           send "onfound" length
  310.  
  311.           // get keycode and convert to lower case
  312.           p = getkey | 020h
  313.           case p
  314.  
  315.             when <y>, <o>, <a>
  316.               undobegin
  317.               l = (replace searchstr replstr  (sub 'r' '' options) + "*z") - 1
  318.               if not (pos 'r' options) then
  319.                 right l
  320.               end
  321.               count = count + 1
  322.               if p <> <y> then
  323.                 length = ''
  324.                 if p == <a> then
  325.                   count = count + (replace searchstr replstr  options + "az")
  326.                 end
  327.               end
  328.               undoend
  329.  
  330.             when <u>
  331.               if count then
  332.                 undo
  333.                 count = count - 1
  334.                 if pos 'r' options then
  335.                   right 1
  336.                 else
  337.                   if getcol == 1 then
  338.                     if up then
  339.                       col 16000
  340.                     end
  341.                   else
  342.                     left l
  343.                   end
  344.                 end
  345.               end
  346.  
  347.             when <n>
  348.                // do nothing
  349.  
  350.             when <r>
  351.                options = if? (pos 'r' options) (sub 'r' '' options)  options + 'r'
  352.  
  353.             otherwise
  354.               if not count then
  355.                 count = '0'
  356.               end
  357.               break
  358.           end
  359.         end
  360.       until not length
  361.  
  362.       if title then
  363.         settitle title
  364.       end
  365.  
  366.       return count
  367.     end
  368.  
  369.  
  370.     // search for a multi-string search argument
  371.     function  search (searchstr reverse rep refopt refrepl)
  372.  
  373.       var replstr
  374.       var options
  375.  
  376.       // split up search multi-string
  377.       if pos '/' searchstr then
  378.         n = splitstr '' searchstr  ref searchstr  ref replstr  ref options
  379.         if n > 1 then
  380.           if n == 2 then
  381.             options = replstr
  382.             replstr = ''
  383.             // case sensitive
  384.             if not options then
  385.               options = 'c'
  386.             end
  387.           end
  388.         end
  389.       end
  390.  
  391.       if searchstr then
  392.  
  393.         // default options
  394.         if not options then
  395.           options = _SearchOpt
  396.           if n > 2 then
  397.             options = options + _ReplaceOpt
  398.           end
  399.         end
  400.  
  401.         // reverse search direction if specified
  402.         if reverse then
  403.           options = if pos 'r' options then
  404.                       sub 'r' '' options
  405.                     else
  406.                       options + 'r'
  407.                     end
  408.         end
  409.  
  410.         // remove global for repeat find
  411.         if rep and (pos 'g' options) then
  412.           options = sub 'g' '' options
  413.         end
  414.  
  415.         // return values for calling function to check
  416.         refopt  = options
  417.         refrepl = n >= 3
  418.  
  419.         // resurface marked window for block search
  420.         if pos 'b' options then
  421.           buffer = getmarkbuf
  422.           if buffer and buffer <> getcurrbuf then
  423.             currwin (getcurswin (getcurrcurs buffer))
  424.           end
  425.         end
  426.  
  427.         // search and replace
  428.         if n >= 3 then
  429.  
  430.           // do the replace
  431.           if pos 'a' options then
  432.             replace searchstr replstr options
  433.           else
  434.             replver searchstr replstr options
  435.           end
  436.  
  437.         // search only
  438.         else
  439.           find searchstr options
  440.         end
  441.       end
  442.     end
  443.  
  444.     // hot key for the file mgr and file picklists
  445.     function onhotkey (character)
  446.       searchstr = '^[~]' + (upcase character)
  447.       if find searchstr 'x' then
  448.         adjustrow getviewrows / 3
  449.         return
  450.       else
  451.         line = getrow
  452.         gotopos 1 1
  453.         if find searchstr 'x*' then
  454.           adjustrow getviewrows / 3
  455.           return
  456.         end
  457.         // not found
  458.         beep 320 70
  459.         row line
  460.       end
  461.     end
  462.  
  463.  
  464.   object  mon
  465.  
  466.     // erase key macros
  467.     function  erasekey2 (options)
  468.       if erasekey options then
  469.         _kd = TRUE
  470.         display
  471.         say (if? (pos options 'a') "All keys macros erased"
  472.                                    "Scrap key macro erased")
  473.       end
  474.     end
  475.  
  476.     // toggle the key macro record mode
  477.     function  record
  478.       if not playing? then
  479.         _kd = TRUE
  480.         if not setting? 'R' then
  481.           erasekey
  482.           record_on = TRUE
  483.         end
  484.         setting 'R' TOGGLE
  485.         say "Record" + (if? record_on "ing..." " OFF")
  486.       end
  487.     end
  488.  
  489.     // play a key macro
  490.     function  play (keymacro)
  491.       setdisplay OFF
  492.       if not (playkey keymacro) then
  493.         say "No key macro to play." 'b'
  494.       end
  495.       setdisplay ON
  496.     end
  497.  
  498.  
  499. // ───────────────────────────────────────────────────────────────────
  500. //  Edit windows and File Manager windows
  501. // ───────────────────────────────────────────────────────────────────
  502.  
  503.   object  edit_fmgr
  504.  
  505.     // close all windows
  506.     function  closeall (options)
  507.       setxobj "__G" ON 'a'
  508.       begdesk
  509.       while getwincount and (send "close" options) end
  510.       enddesk
  511.       setxobj "__G" OFF 'a'
  512.     end
  513.  
  514.     // move the cursor to any edge of a mark
  515.     function  gotomark (options)
  516.       if mark? then
  517.  
  518.         window = getcurswin (getcurrcurs (getmarkbuf))
  519.         if window then
  520.           currwin window
  521.         end
  522.  
  523.         // left or right
  524.         if pos 'l' options then
  525.           col (getmarkleft)
  526.         elseif pos 'r' options then
  527.           col (getmarkright)
  528.         end
  529.  
  530.         // top or bottom
  531.         if pos 't' options then
  532.           row (getmarktop)
  533.         elseif pos 'b' options then
  534.           row (getmarkbot)
  535.         end
  536.  
  537.         if window then
  538.           send "onfound"
  539.         end
  540.  
  541.       else
  542.         say "Block not found" 'b'
  543.       end
  544.     end
  545.  
  546.     // goto a bookmark with message
  547.     function  gotobook2 (bookmark)
  548.       msg = "Bookmark '" + bookmark + "'"
  549.       if gotobook bookmark then
  550.         window = getcurswin (getcurrcurs (getbookbuf bookmark))
  551.         if window <> getcurrwin then
  552.           currwin window
  553.         end
  554.         display
  555.         say msg
  556.       else
  557.         say msg + " not found"  'b'
  558.       end
  559.     end
  560.  
  561.     // prompt to goto a bookmark
  562.     function  askbook (msg)
  563.       askx (if? msg msg "Bookmark Name") "_book" "gotobook2"
  564.     end
  565.  
  566.     // cycle though all existing bookmarks
  567.     function  cyclebook
  568.       repeat
  569.         l = _lb
  570.         bookmark = if? l (getprevbook l) (getcurrbook)
  571.         buffer = getcurrbuf
  572.         while not bookmark and buffer do
  573.           buffer = getprevbuf buffer
  574.           bookmark = getcurrbook buffer
  575.         end
  576.         _lb = bookmark
  577.       until bookmark or not l
  578.       gotobook2 bookmark
  579.     end
  580.  
  581.     // print the current buffer or mark
  582.     function  print (options)
  583.       printstr _PrtIni
  584.       header = _PrtHdr
  585.       if not (posnot ' ' header) or (dir? (getbufname)) then
  586.         date = getdate
  587.         header = getbufname + "   (" + date [posnot ' ' date : TO_END] +
  588.                                  ' ' + gettime + ')'
  589.       end
  590.       if not ( if pos 'b' options  then printblock _PrtDev header ''
  591.                 else    printbuf _PrtDev header end ) then
  592.         say "Print failed" 'b'
  593.       end
  594.     end
  595.  
  596.     // replace/append/cancel or ok/cancel menus
  597.     function  askrac (file menuname)
  598.       if _ConRpl == 'y' and (locatefile file) then
  599.         locase (popup (if? menuname menuname "rac" )
  600.                         file + " Exists" +
  601.                         (if? menuname == "ok" ". Replace?")) [1]
  602.       else
  603.         'r'
  604.       end
  605.     end
  606.  
  607.     // generic prompt to change a configuration variable
  608.     function  askc (pstring variable history)
  609.       newvalue = ask pstring history (lookup variable "prf")
  610.       if newvalue then
  611.         setxobj variable newvalue "prf"
  612.       end
  613.     end
  614.  
  615.     // prompts to change specific configuration variables
  616.     function  askbinary  askc "Binary Line Length"  "BinaryLength"     end
  617.     function  askdelim   askc "Line Delimiter String in Hex" "LineDlm" end
  618.     function  asktabw    askc "Tab Width"      "TabWidth"    end
  619.     function  asktabv    askc "Variable Tabs"  "VarTabs"     end
  620.     function  asklmarg   askc "Left Margin"    "LMargin"     end
  621.     function  askrmarg   askc "Right Margin"   "RMargin"     end
  622.     function  askclip    askc "Clipboard Name" "ClipName"    end
  623.     function  askprthdr  askc "Current Header/Footer" "PrtHdr" end
  624.  
  625.     // generic prompt with command execution
  626.     function  askx (pstring history func parm2)
  627.       parm1 = ask pstring history
  628.       if parm1 then
  629.         send func parm1 parm2
  630.         if history then
  631.           addhistory history parm1
  632.         end
  633.         return 1
  634.       end
  635.     end
  636.  
  637.     // open prompt
  638.     function  askopen
  639.       file = ask "[file/ibcenz] Open" "_load"
  640.       if file then
  641.         // addhistory not needed for open
  642.         open file
  643.       end
  644.     end
  645.  
  646.     // open binary prompt
  647.     function  askopenb
  648.       askx "File to open in Binary Mode" "_load" "open" 'b'
  649.     end
  650.  
  651.     // macro expression prompt
  652.     function  askeval
  653.       if askx "Macro Expression" "_cmd" "eval" then
  654.         error = geterror 'c'
  655.         if error then
  656.           msgbox "Expression column " + (geterror 'k') +
  657.                  ": " + (errormsg error)  "Error" 'b'
  658.         end
  659.       end
  660.     end
  661.  
  662.     // prompt to include a macro
  663.     function  askimacro
  664.       askx "Include Macro File"  "_load" "includemacro2"
  665.     end
  666.  
  667.     // prompt to run a macro
  668.     function  askrmacro
  669.       askx "Run Macro File"  "_load" "runmacro2"
  670.     end
  671.  
  672.     // prompt to compile a macro
  673.     function  askcmacro
  674.       askx "Compile Macro File"  "_load" "compilemacro2"
  675.     end
  676.  
  677.     // macro picklist
  678.     function  pickmacro
  679.       macro = askfile getbootpath + "MACRO\\*.X" "Select a macro to run"
  680.                       _FmgrSort _FmgrOpt "maclist"
  681.       if macro then
  682.         runmacro macro
  683.       end
  684.     end
  685.  
  686.     // DOS command prompt
  687.     function  askrun
  688.       askx "DOS Command" "_os" "run" "ck"
  689.     end
  690.  
  691.     // prompt to capture DOS output
  692.     function  askruncap
  693.       askx "Capture DOS Output" "_os" "runcap" 'c'
  694.     end
  695.  
  696.     // open key macro file with messages
  697.     function  openkey2 (file)
  698.       if openkey file then
  699.         say (getname file) + " loaded"
  700.       else
  701.         say "Load failed" 'b'
  702.       end
  703.     end
  704.  
  705.     // prompt to open a key macro file
  706.     function  askopenkey
  707.       file = ask "Key macro filename" "_load"
  708.       if file then
  709.         openkey2 (qualify (defext file "mac") (getbufname))
  710.       end
  711.     end
  712.  
  713.     // prompt to save current key macros
  714.     function  asksavekey
  715.       file = ask "Save current key macros as" "_load"
  716.       if file then
  717.         file = qualify (defext file "mac") (getbufname)
  718.         if pos (askrac file "ok") "or" 'i' then
  719.           if not savekey file then
  720.             say "Save failed" 'b'
  721.           end
  722.         end
  723.       end
  724.     end
  725.  
  726.     // search files for a string in multi-string format with msgs
  727.     function  searchfiles (s)
  728.       var searchstr
  729.       var filespec
  730.       var options
  731.       n = splitstr '' s  ref searchstr  ref filespec  ref options
  732.       if n < 3 then
  733.         options = _SearchOpt
  734.         if n < 2 then
  735.           filespec = '.'
  736.         end
  737.       end
  738.       if searchstr then
  739.         r = scanfiles filespec searchstr options
  740.         if r <= 0 then
  741.           say (if? r filespec s) + " not found" 'b'
  742.         else
  743.           addhistory "_find" (joinstr '' searchstr options)
  744.         end
  745.       end
  746.     end
  747.  
  748.     // prompt to scan files for a string
  749.     function  askscan
  750.       scanstring = if _PromptStyle == 'd' then
  751.                      scandlg
  752.                    else
  753.                      ask "[string/files/iwx] Scan" "_scan"
  754.                    end
  755.       if scanstring then
  756.         searchfiles scanstring
  757.         addhistory "_scan" scanstring
  758.       end
  759.     end
  760.  
  761.     // reload the current file from disk
  762.     function  reopen (file)
  763.       open (if? file file getbufname) 'r'
  764.     end
  765.  
  766.     // open last file or directory
  767.     function  openlast
  768.       file = gethiststr "_load"
  769.       if file then
  770.         open file
  771.       end
  772.     end
  773.  
  774.     // open an AML configuration file in boot directory
  775.     function  opencfg (file)
  776.       open (bootpath  file + ".aml")
  777.     end
  778.  
  779.     // quick reference help
  780.     function  quickref (options openopt)
  781.       quickfile = getbootpath + (if? options <> 'o' "DOC\\") +
  782.                     case options [1]
  783.                       when 'l'  "LANGUAGE.DOX"
  784.                       when 'f'  "FUNCTION.DOX"
  785.                       when 'q'  "QUICKFUN.DOX"
  786.                       when 'o'  "ORDERFRM.DOC"
  787.                       when 't'  "TIPS.DOX"
  788.                       otherwise "USER.DOX"
  789.                     end
  790.       if (wintype? "edit") and (pos 'w' options) then
  791.         wordstr = send "getword" "a-zA-Z0-9?"
  792.       end
  793.       open quickfile openopt
  794.       if wordstr then
  795.         gotopos 1 1
  796.         // find string in reference
  797.         if find (char 0ffh) + wordstr + (char 0ffh) then
  798.           right
  799.           send "onfound" (sizeof wordstr)
  800.         // not found? then try function header in EXT.AML
  801.         elseif poschar 'fq' options then
  802.           close
  803.           ext = bootpath "EXT.AML"
  804.           closeit = _MultCopy == 'n' and not (findbuf ext)
  805.           open ext openopt
  806.           gotopos 1 1
  807.           n = find "function #" + wordstr  'x'
  808.           if n then
  809.             send "onfound" n
  810.           else
  811.             // still not found? then go back to the reference
  812.             if closeit then
  813.               close
  814.             end
  815.             open quickfile openopt
  816.           end
  817.         end
  818.       end
  819.     end
  820.  
  821.     // popup menu to change the default prompt style
  822.     function  askprompt
  823.       menu "prompts"
  824.         item " &Command line" 1
  825.         item " &One-line box" 2
  826.         item " &Two-line box" 3
  827.         item " &Dialog box"   4
  828.       end
  829.       newtype = popup (getcurrbuf) "Select a Prompt Style" 25
  830.       if newtype then
  831.         setobj _PromptStyle "c12d" [newtype] "prf"
  832.       end
  833.       destroybuf "prompts"
  834.     end
  835.  
  836.  
  837. // ───────────────────────────────────────────────────────────────────
  838. //  Prompts and Edit windows
  839. // ───────────────────────────────────────────────────────────────────
  840.  
  841.   object  prompt
  842.  
  843.     // support for cua-style <shift> key marking
  844.     function  smark
  845.       if shiftkey? then
  846.         if _shfx then
  847.           undobegin
  848.           destroymark
  849.           markstream _shfx _shfx _shfy _shfy
  850.           _shfx = ''
  851.           _shfy = ''
  852.         end
  853.         extendmark
  854.       end
  855.     end
  856.  
  857.     // set anchor for shift-key marking
  858.     function  shiftdown
  859.       _shfx = getcol
  860.       _shfy = getrow
  861.       pass
  862.     end
  863.  
  864.     // end shift-key mark
  865.     function  shiftup
  866.       stopmark
  867.       pass
  868.       undoend
  869.     end
  870.  
  871.     // backspace in a prompt
  872.     function  backsp
  873.       if getcol > 1 then
  874.         left
  875.         delchar
  876.       end
  877.     end
  878.  
  879.     // get the word at the cursor
  880.     function  getword (charset column mark)
  881.       if not column then
  882.         column = getcol
  883.       end
  884.       if column <= getlinelen then
  885.         if not charset then
  886.           charset = _CSet
  887.         end
  888.         b = posnot charset (gettext column)
  889.         if b <> 1 then
  890.           b = if? b  column + b - 2  getlinelen
  891.           a = posnot charset (gettext 1 column) 'r'
  892.           a = if? a  a + 1  1
  893.           if mark then
  894.             undobegin
  895.             destroymark
  896.             markchar a b
  897.             undoend
  898.           else
  899.             gettext a  b - a + 1
  900.           end
  901.         end
  902.       end
  903.     end
  904.  
  905.     // mark the word at the cursor using getword
  906.     function  markword (charset)
  907.       getword charset '' 1
  908.     end
  909.  
  910.     // mark to end-of-line
  911.     function  markeol
  912.       undobegin
  913.       destroymark
  914.       if getcol <= getlinelen then
  915.         markchar (getcol) (getlinelen)
  916.       end
  917.       undoend
  918.     end
  919.  
  920.     // delete a block
  921.     function  deleteblock2
  922.       if getmarkbuf == getcurrbuf then
  923.         deleteblock
  924.       else
  925.         if wintype? "edit" then
  926.           if _DelLine == 'y' then
  927.             delline
  928.           end
  929.         end
  930.       end
  931.     end
  932.  
  933.     // prompt to enter character literally
  934.     function  literal
  935.       say "Enter Literal..."
  936.       queue <char> (char getkey & 0ffh)
  937.     end
  938.  
  939.     // ascii chart with character entry
  940.     function  asciilist
  941.       buffer = asciibuf
  942.       // name it so the position can be remembered
  943.       setbufname "_asc"
  944.       character = (popup buffer '' 13) [10]
  945.       destroybuf
  946.       if character then
  947.         queue <char> character
  948.       end
  949.     end
  950.  
  951.     // support for file name completion (open prompts only)
  952.     function  askcomplete
  953.       if gethistname == "_load" then
  954.         filespec = gettext
  955.         if filespec then
  956.           if not pos "*.*" filespec then
  957.             filespec = filespec + (if? (pos '.' filespec) '*' "*.*")
  958.           end
  959.         else
  960.           filespec = "*.*"
  961.         end
  962.         file = picklist (qualify filespec (getbufname (getwinbuf (getprevwin))))
  963.         if file then
  964.           col 1
  965.           delchar (getlinelen)
  966.           writetext file
  967.           return file
  968.         end
  969.       end
  970.     end
  971.  
  972.     // get the first line of text in the default mark
  973.     function  getmarktext
  974.       if mark? then
  975.         buffer = getmarkbuf
  976.         topline = getmarktop
  977.         if getmarktype == 'l' then
  978.           gettext (getlinebeg topline buffer) (getlinelen topline buffer)
  979.                   (getmarktop) buffer
  980.         else
  981.           gettext (getmarkleft) (getmarkcols) topline buffer
  982.         end
  983.       end
  984.     end
  985.  
  986.     // copy or copy-append to the clipboard
  987.     function  copy (options)
  988.  
  989.       if mark? then
  990.         currentbuf = getcurrbuf
  991.  
  992.         clip = _ClipName
  993.         destroymark clip
  994.         copymark (getmarkuse) clip
  995.  
  996.         // copy
  997.         if options and (buffer? clip) then
  998.           if getmarktype <> 'l' then
  999.             insline '' '' (getlines clip) clip
  1000.           end
  1001.           copyblock clip clip 1 (getlines clip)
  1002.           markline 1 (getlines clip) clip clip
  1003.  
  1004.         // copy append
  1005.         else
  1006.           destroybuf clip
  1007.           createbuf clip
  1008.           copyblock clip clip
  1009.           if getmarktype == 'l' then
  1010.             delline 1 1 clip
  1011.           end
  1012.         end
  1013.         currbuf currentbuf
  1014.       end
  1015.     end
  1016.  
  1017.     // cut or cut-append to the clipboard
  1018.     function  cut (options)
  1019.       if mark? then
  1020.         copy options
  1021.         deleteblock
  1022.       end
  1023.     end
  1024.  
  1025.     // enter a character or string into the current prompt
  1026.     function  write (charstring)
  1027.       writetext charstring
  1028.     end
  1029.  
  1030.  
  1031. // ───────────────────────────────────────────────────────────────────
  1032. //  Edit windows
  1033. // ───────────────────────────────────────────────────────────────────
  1034.  
  1035.   object  edit
  1036.  
  1037.     // mark a paragraph
  1038.     function  markpara
  1039.  
  1040.       if getlinelen then
  1041.  
  1042.         undobegin
  1043.         destroymark
  1044.  
  1045.         // find the beginning of the paragraph
  1046.         pushcursor
  1047.         while up and getlinelen end
  1048.         if not getlinelen then
  1049.           down
  1050.         end
  1051.         markline
  1052.         popcursor
  1053.  
  1054.         // find the end of the paragraph
  1055.         pushcursor
  1056.         while down and getlinelen end
  1057.         if not getlinelen then
  1058.           up
  1059.         end
  1060.         markline
  1061.         popcursor
  1062.  
  1063.         undoend
  1064.  
  1065.         return 1
  1066.       end
  1067.     end
  1068.  
  1069.     // setup for insert-above (copy, move, paste - lineblocks only)
  1070.     function  begabove
  1071.       _ba = ''
  1072.       undobegin
  1073.       if _InsAbove == 'y' and getmarktype == 'l' then
  1074.         _ba = 1
  1075.         if not up then
  1076.           insabove
  1077.           up
  1078.           _ba = 2
  1079.         end
  1080.       end
  1081.     end
  1082.  
  1083.     // end insert-above
  1084.     function  endabove
  1085.       case _ba
  1086.         when 1 down
  1087.         when 2 delline
  1088.       end
  1089.       undoend
  1090.     end
  1091.  
  1092.     // paste or paste-over from the clipboard
  1093.     function  paste (options)
  1094.       if mark? _ClipName then
  1095.         destroymark
  1096.         copymark _ClipName (getmarkuse)
  1097.         if options then
  1098.           copyblockover
  1099.         else
  1100.           begabove
  1101.           copyblock
  1102.           endabove
  1103.         end
  1104.       else
  1105.         say "Nothing to paste" 'b'
  1106.       end
  1107.     end
  1108.  
  1109.     // clear the clipboard
  1110.     function  clear
  1111.       destroybuf _ClipName
  1112.     end
  1113.  
  1114.     // copy a block
  1115.     function  copyblock2
  1116.       if mark? then
  1117.         begabove
  1118.         if not copyblock then
  1119.           say "Copy failed" 'b'
  1120.         end
  1121.         endabove
  1122.       else
  1123.         if _CopyLine == 'y' then
  1124.           undobegin
  1125.           markline
  1126.           copyblock
  1127.           destroymark
  1128.           undoend
  1129.         end
  1130.       end
  1131.     end
  1132.  
  1133.     // move a block
  1134.     function  moveblock2
  1135.       begabove
  1136.       if getmarktop < getviewtop then
  1137.         y = 1 + getrow - (apparentrow  getviewtop - getrow)
  1138.       end
  1139.       if moveblock then
  1140.         if y then
  1141.           adjustrow y
  1142.         end
  1143.       else
  1144.         say "Move failed" 'b'
  1145.       end
  1146.       endabove
  1147.     end
  1148.  
  1149.     // move a block over text
  1150.     function  moveblockover
  1151.       if mark? then
  1152.         undobegin
  1153.         // use a temporary clipboard
  1154.         clip = _ClipName
  1155.         setobj ClipName 'T' 'prf'
  1156.         copy
  1157.         fillblock ' '
  1158.         paste 'o'
  1159.         setobj ClipName clip 'prf'
  1160.         destroybuf 'T'
  1161.         undoend
  1162.       end
  1163.     end
  1164.  
  1165.     // reformat a block or the current paragraph
  1166.     function  formatblock2 (options)
  1167.       undobegin
  1168.       if not mark? then
  1169.         if markpara "tb" then
  1170.           markcolumn (getcol) _RMargin (getmarktop) (getmarkbot)
  1171.           flag = ON
  1172.         end
  1173.       end
  1174.       // special case for single lines
  1175.       if getmarkrows == 1 and getcol < getlinebeg then
  1176.         delchar getlinebeg - getcol
  1177.       else
  1178.         formatblock _LMargin _RMargin options
  1179.       end
  1180.       if flag then
  1181.         destroymark
  1182.       end
  1183.       undoend
  1184.     end
  1185.  
  1186.     // simple text quoting support for a block or the current paragraph
  1187.     function  quote
  1188.       undobegin
  1189.       if not mark? then
  1190.         tempmark = TRUE
  1191.         markpara
  1192.       end
  1193.       if mark? then
  1194.         shiftblock 1 '' '>'
  1195.         if tempmark then
  1196.           destroymark
  1197.         end
  1198.       else
  1199.         say "Nothing to quote"
  1200.       end
  1201.       undoend
  1202.     end
  1203.  
  1204.     // sort a block
  1205.     function  sortblock2
  1206.       sortblock
  1207.         // scrollock ON=descending    // insert ON=ignore case
  1208.         (if? (shiftkey? 10h) 'd')  +  (if? (insert?) 'i')
  1209.  
  1210.     end
  1211.  
  1212.     // prompt to fill a block with a string
  1213.     function  fillblock2
  1214.       askx "Enter fill string" '' "fillblock"
  1215.     end
  1216.  
  1217.     // prompt to save a block
  1218.     function  saveblock2 (options)
  1219.       var c1
  1220.       var c2
  1221.       if mark? then
  1222.         file = ask "Save block as" "_load"
  1223.         if file then
  1224.           file = qualify file (getbufname)
  1225.           addhistory "_load" file
  1226.           if fileattr? file 'r' then
  1227.             say "Read Only!" 'b'
  1228.           else
  1229.             action = locase (askrac file)
  1230.             if pos action "ra" then
  1231.               send "oncomment" file ref c1 ref c2
  1232.               options = _SaveOpt + options
  1233.               if not saveblock file
  1234.                  (if? (pos 'e' options) 'e' + _TabWidth) + options +
  1235.                  (if? action == 'a' 'a')  ''
  1236.                  '' '' (if? c1 c1 + _FoldSign) c2 then
  1237.                 msgbox "Save Failed!" "Error!" 'b'
  1238.               end
  1239.             end
  1240.           end
  1241.         end
  1242.       else
  1243.         say "No marked block" 'b'
  1244.       end
  1245.     end
  1246.  
  1247.     // left justify, center, or right justify a block
  1248.     function  justblock2 (options)
  1249.       justblock options '' _LMargin _RMargin
  1250.     end
  1251.  
  1252.     // destroy open and closed folds
  1253.     function  destroyfold2
  1254.       undobegin
  1255.       if not fold? then
  1256.         closefold
  1257.       end
  1258.       destroyfold
  1259.       undoend
  1260.     end
  1261.  
  1262.     // do fold operations on entire file
  1263.     function  foldall (options)
  1264.       undobegin
  1265.       usemark 'T'
  1266.       markline 1 (getlines)
  1267.       foldblock options
  1268.       destroymark
  1269.       usemark
  1270.       undoend
  1271.     end
  1272.  
  1273.     // fold a block or the current paragraph
  1274.     function  foldblock2
  1275.       undobegin
  1276.       if mark? then
  1277.         foldblock
  1278.       elseif markpara then
  1279.         foldblock
  1280.         destroymark
  1281.       end
  1282.       undoend
  1283.     end
  1284.  
  1285.     // fold a block and destroy subfolds
  1286.     function  foldflat
  1287.       undobegin
  1288.       foldblock 'ds'
  1289.       foldblock
  1290.       undoend
  1291.     end
  1292.  
  1293.     // fold or unfold a line
  1294.     function  foldline (options)
  1295.       undobegin
  1296.       usemark 'T'
  1297.       markline
  1298.       unfold = pos 'u' options
  1299.       if fold? then
  1300.         foldblock 'd'
  1301.         if not unfold or getmarkrows > 1 then
  1302.           bottom = actualrow (if? unfold -1 1) (getmarkbot)
  1303.           if not (getfold 'o' bottom) then
  1304.             markline (getrow) bottom
  1305.           end
  1306.           foldblock
  1307.         end
  1308.       else
  1309.         if not unfold then
  1310.           foldblock
  1311.         end
  1312.       end
  1313.       destroymark
  1314.       usemark
  1315.       undoend
  1316.     end
  1317.  
  1318.     // detab or entab the current file
  1319.     // (+width=detab, -width=entab)
  1320.     function  tabfile (width)
  1321.       undobegin
  1322.       usemark 'T'
  1323.       markline 1 (getlines)
  1324.       tabblock (if? width width _TabWidth)
  1325.       destroymark
  1326.       usemark
  1327.       undoend
  1328.     end
  1329.  
  1330.     // insert a line after the current line with autoindent
  1331.     function  insline2
  1332.       undobegin
  1333.       insline
  1334.       if setting? 'A' then
  1335.         if getlinelen then
  1336.           col (getlinebeg)
  1337.         else
  1338.           nextline = getrow + 2
  1339.           if getlinelen nextline then
  1340.             col (getlinebeg nextline)
  1341.           end
  1342.         end
  1343.       end
  1344.       down
  1345.       undoend
  1346.     end
  1347.  
  1348.     // swap the current line with the next line
  1349.     function  swapline
  1350.       undobegin
  1351.       usemark 'T'
  1352.       markline
  1353.       stopmark
  1354.       down
  1355.       moveblock
  1356.       destroymark
  1357.       usemark
  1358.       undoend
  1359.     end
  1360.  
  1361.     // center the current line
  1362.     function  centerline
  1363.       undobegin
  1364.       usemark 'T'
  1365.       markline
  1366.       justblock 'c' '' _LMargin _RMargin
  1367.       destroymark
  1368.       usemark
  1369.       undoend
  1370.     end
  1371.  
  1372.     // comment or uncomment a line
  1373.     function  commentline (c1 c2)
  1374.       if not c1 then
  1375.         send "oncomment" (getbufname) ref c1 ref c2
  1376.         if not c1 then
  1377.           c1 = '>'
  1378.         end
  1379.       end
  1380.       undobegin
  1381.       column = getlinebeg
  1382.       if (gettext column (sizeof c1)) == c1 then
  1383.         delchar (sizeof c2) getlinelen - (sizeof c2) + 1
  1384.         delchar (sizeof c1) column
  1385.       elseif getlinelen then
  1386.         instext c1 (getlinebeg)
  1387.         if column then
  1388.           ovltext c2  getlinelen + 1
  1389.         end
  1390.       end
  1391.       down
  1392.       undoend
  1393.     end
  1394.  
  1395.     // find the previous word
  1396.     function  prevword
  1397.       while getcol > 1 and (poschar _CSet (getchar)) do
  1398.         left
  1399.       end
  1400.       find _CSet "[r"
  1401.       while getcol > 1 and (poschar _CSet (getchar getcol - 1)) do
  1402.         left
  1403.       end
  1404.     end
  1405.  
  1406.     // find the next word
  1407.     function  nextword
  1408.       while poschar _CSet (getchar) do
  1409.         right
  1410.       end
  1411.       find _CSet '['
  1412.     end
  1413.  
  1414.     // change the case of the word at the cursor
  1415.     function  caseword (options charset)
  1416.       undobegin
  1417.       usemark 'T'
  1418.       markword charset
  1419.       caseblock options
  1420.       destroymark
  1421.       usemark
  1422.       undoend
  1423.     end
  1424.  
  1425.     // open the filename at the cursor
  1426.     function  openword (charset)
  1427.       file = getword (if? charset charset _CSetB)
  1428.       if file then
  1429.         open file
  1430.       end
  1431.     end
  1432.  
  1433.     // delete the character at the cursor
  1434.     function  delchar2
  1435.       undobegin
  1436.       if getcol > getlinelen and _DelJoin == 'y' then
  1437.         joinline
  1438.       else
  1439.         delchar
  1440.         if setting? 'L' then
  1441.           livewrap
  1442.         end
  1443.       end
  1444.       undoend
  1445.     end
  1446.  
  1447.     // backspace
  1448.     function  backsp
  1449.       undobegin
  1450.       if getcol > 1 then
  1451.         left
  1452.         if not insert? and _BakOvl == 'y' then
  1453.           ovltext ' '
  1454.         else
  1455.           delchar
  1456.           if setting? 'L' then
  1457.             livewrap
  1458.           end
  1459.         end
  1460.       elseif getrow > 1 and _BakJoin == 'y' then
  1461.         up
  1462.         col getlinelen + 1
  1463.         joinline
  1464.       end
  1465.       undoend
  1466.     end
  1467.  
  1468.     // delete right word
  1469.     function  delword (charset)
  1470.       if not charset then
  1471.         charset = _CSet
  1472.       end
  1473.       undobegin
  1474.       if getcol > getlinelen then
  1475.         joinline
  1476.       else
  1477.         p = posnot charset (gettext (getcol))
  1478.         if p > 1 then
  1479.           delchar p - 1
  1480.         end
  1481.         delchar (
  1482.           if p then
  1483.             if getchar == ' ' and
  1484.                  (getcol == 1 or
  1485.                  (posnot charset (getchar getcol - 1))) then
  1486.               (posnot ' ' (gettext (getcol))) - 1
  1487.             else
  1488.               p == 1
  1489.             end
  1490.           else
  1491.             getlinelen
  1492.           end
  1493.         )
  1494.       end
  1495.       if setting? 'L' then
  1496.         livewrap
  1497.       end
  1498.       undoend
  1499.     end
  1500.  
  1501.     // splitline with autoindent
  1502.     function splitline2 (column)
  1503.       undobegin
  1504.       b = getlinebeg
  1505.       if splitline column then
  1506.         if not setting? 'A' then
  1507.           b = _LMargin
  1508.         end
  1509.         if b > 1 then
  1510.           pushcursor
  1511.           down
  1512.           usemark 'T'
  1513.           markline
  1514.           shiftblock (if? getcol > b  b  (getcol)) - 1
  1515.           destroymark
  1516.           usemark
  1517.           popcursor
  1518.         end
  1519.       end
  1520.       undoend
  1521.     end
  1522.  
  1523.     // <enter> key behavior
  1524.     function  enter
  1525.  
  1526.       // terminate a word for text translation
  1527.       lastrow = getrow
  1528.       if getcol == getlinelen + 1 and getlinelen then
  1529.         if setting? 'T' then
  1530.           send <char> ' '
  1531.         end
  1532.       end
  1533.  
  1534.       if getrow == lastrow then
  1535.         case (if? (insert?) _EnterIns _EnterOvl)
  1536.           when 'i'
  1537.             insline2
  1538.           when 's'
  1539.             if fold? then
  1540.               insline2
  1541.             else
  1542.               startcolumn = getlinebeg
  1543.               length = getlinelen
  1544.               splitline2
  1545.               down
  1546.               if setting? 'A' then
  1547.                 if length then
  1548.                   col startcolumn
  1549.                 end
  1550.               else
  1551.                 startcolumn = _LMargin
  1552.                 col (if? startcolumn startcolumn 1)
  1553.               end
  1554.             end
  1555.           otherwise
  1556.             down
  1557.             col (if? (getlinelen) (getlinebeg) _LMargin)
  1558.         end
  1559.       end
  1560.     end
  1561.  
  1562.     // for use by variable tab right
  1563.     function  vtabr
  1564.       i = 1
  1565.       while i <= arg do
  1566.         if (arg i) <= getcol then
  1567.           i = i + 1
  1568.         else
  1569.           return arg i
  1570.         end
  1571.       end
  1572.       return 0
  1573.     end
  1574.  
  1575.     // for use by variable tab left
  1576.     function  vtabl
  1577.       i = arg
  1578.       while i do
  1579.         if (arg i) >= getcol then
  1580.           i = i - 1
  1581.         else
  1582.           return arg i
  1583.         end
  1584.       end
  1585.       return 0
  1586.     end
  1587.  
  1588.     // tab support
  1589.     function  tabfunc (next)
  1590.  
  1591.       oldcolumn = getcol
  1592.  
  1593.       // smart tabs
  1594.       if setting? 'S' then
  1595.         prevline = getrow - 1
  1596.         while prevline and not (getlinelen prevline) do
  1597.           prevline = prevline - 1
  1598.         end
  1599.         if prevline then
  1600.           pushcursor
  1601.           row prevline
  1602.           send (if? next "nextword" "prevword")
  1603.           if prevline == getrow then
  1604.             newcolumn = getcol
  1605.           end
  1606.           popcursor
  1607.         end
  1608.       end
  1609.  
  1610.       // variable tabs
  1611.       if not newcolumn then
  1612.         if setting? 'V' then
  1613.           newcolumn = eval (if? next "vtabr " "vtabl ") + _VarTabs
  1614.         end
  1615.  
  1616.         // standard interval tabs
  1617.         if not newcolumn then
  1618.           width = _TabWidth
  1619.           if not width then
  1620.             width = 8
  1621.           end
  1622.           newcolumn = oldcolumn +
  1623.                         if next then
  1624.                           width - (oldcolumn - 1) mod width
  1625.                         elseif oldcolumn > 1 then
  1626.                           -((oldcolumn - 2) mod width + 1)
  1627.                         end
  1628.         end
  1629.       end
  1630.  
  1631.       // move to tabstop and shift text if needed
  1632.       if newcolumn then
  1633.         if _TabShift == 'y' and insert? then
  1634.           if newcolumn < oldcolumn then
  1635.             delchar  oldcolumn - newcolumn  newcolumn
  1636.           elseif newcolumn > oldcolumn then
  1637.             instext (copystr ' ' newcolumn - oldcolumn)
  1638.           end
  1639.         end
  1640.         col newcolumn
  1641.       end
  1642.     end
  1643.  
  1644.     // tab left and right
  1645.     function  tabright    tabfunc 1  end
  1646.     function  tableft     tabfunc    end
  1647.  
  1648.     // prompt to verify close
  1649.     function  close?
  1650.       if bufchanged? and not getprevcurs then
  1651.         savechanges = popup "ync"  "Save changes to " +
  1652.                                         (getname (getbufname)) + '?'
  1653.         if savechanges == "Yes" then
  1654.           save
  1655.         end
  1656.         icompare savechanges "Yes" "No"
  1657.       else
  1658.         1
  1659.       end
  1660.     end
  1661.  
  1662.     // close an edit window
  1663.     function  close (options)
  1664.       if pos 's' options then
  1665.         if save then
  1666.           pass
  1667.         end
  1668.       elseif close? then
  1669.         pass
  1670.       end
  1671.     end
  1672.  
  1673.     // open and insert prompt
  1674.     function  askinsert
  1675.       file = ask  "File to insert into " + (getname (getbufname)) "_load"
  1676.       if file then
  1677.         // addhistory not needed for open
  1678.         old_size = getlines
  1679.         undobegin
  1680.         open file 'i'
  1681.         // mark the inserted text
  1682.         if not (dir? (getbufname)) then
  1683.           if getlines > old_size then
  1684.             markline  getrow + 1  getrow + getlines - old_size
  1685.           end
  1686.         end
  1687.         undoend
  1688.       end
  1689.     end
  1690.  
  1691.     // prompt to change the current file name
  1692.     function  askname
  1693.       newname = ask  "Rename " + (getname (getbufname)) + " to"  "_load"
  1694.       if newname then
  1695.         case setname newname
  1696.           when -1 say "Failed" 'b'
  1697.           when -2 say "Failed - file already loaded" 'b'
  1698.           otherwise
  1699.             addhistory "_load" (getbufname)
  1700.         end
  1701.       end
  1702.     end
  1703.  
  1704.     // search and replace with messages and highlighting
  1705.     function  search2 (search_str reverse again)
  1706.       var opt
  1707.       var rpl
  1708.       n = search search_str reverse again ref opt ref rpl
  1709.       if n then
  1710.         // replace occurred
  1711.         if rpl then
  1712.           display
  1713.           say (thousands n) + " changes made"
  1714.         // count occurrences
  1715.         elseif pos 'a' opt then
  1716.           display
  1717.           say (thousands n) + " occurrences of '" + search_str + "' found"
  1718.         // search only
  1719.         else
  1720.           onfound n
  1721.         end
  1722.       else
  1723.         display
  1724.         say "'" + search_str + "' not found"  'b'
  1725.       end
  1726.       return n
  1727.     end
  1728.  
  1729.     // find prompt
  1730.     function  askfind (reverse)
  1731.       search_string = if _PromptStyle == 'd' then
  1732.                         finddlg
  1733.                       else
  1734.                         ask "[string/abgirswx] Find"  "_find"
  1735.                       end
  1736.       if search_string then
  1737.         search2 search_string reverse
  1738.         addhistory "_find" search_string
  1739.       end
  1740.     end
  1741.  
  1742.     // replace prompt
  1743.     function  askrepl (reverse)
  1744.       search_string = if _PromptStyle == 'd' then
  1745.                         repldlg
  1746.                       else
  1747.                         ask "[string/replstr/abgirswx] Repl"  "_find"
  1748.                       end
  1749.       if search_string then
  1750.         search2 search_string reverse
  1751.         addhistory "_find" search_string
  1752.       end
  1753.     end
  1754.  
  1755.     // do the last find/replace operation
  1756.     // (reverse=r reverses the search direction)
  1757.     function  findlast (reverse)
  1758.       search2 (gethiststr "_find") reverse TRUE
  1759.     end
  1760.  
  1761.     // incremental search
  1762.     function  isearch
  1763.  
  1764.       var search_string
  1765.  
  1766.       repeat
  1767.  
  1768.         settitle  "I-search for [" + search_string + "] "
  1769.         keycode = getkey
  1770.         options = _SearchOpt
  1771.         new_char = ''
  1772.  
  1773.         case  keycode
  1774.  
  1775.           when <backspace>
  1776.             if search_string then
  1777.               popcursor
  1778.               search_string = if (sizeof search_string) > 1 then
  1779.                                 search_string [1 : (sizeof search_string) - 1]
  1780.                               else
  1781.                                 ''
  1782.                               end
  1783.               if not search_string then
  1784.                 display
  1785.               end
  1786.               options = '*'
  1787.             end
  1788.  
  1789.           when <ctrl p>, <ctrl r>
  1790.             options = 'r'
  1791.  
  1792.           when <ctrl n>, <ctrl l>
  1793.             // do nothing
  1794.  
  1795.           when <ctrl g>, <ctrl b>
  1796.             options = 'g'
  1797.  
  1798.           otherwise
  1799.             keyname = getkeyname keycode
  1800.             if (sizeof keyname) == 3 then
  1801.               pushcursor
  1802.               new_char = keyname [2]
  1803.               options = '*'
  1804.             else
  1805.  
  1806.               // restore window title
  1807.               settitle (getbufname)
  1808.               display
  1809.  
  1810.               // clear all pushed cursors
  1811.               popcursor "ad"
  1812.               addhistory "_find" search_string
  1813.  
  1814.               if keycode <> <enter> and keycode <> <esc> then
  1815.                 queuekey keycode
  1816.               end
  1817.  
  1818.               done = TRUE
  1819.             end
  1820.         end
  1821.  
  1822.         if not done and (search_string or new_char) then
  1823.           new_string = concat search_string new_char
  1824.           str_length = find new_string  _SearchOpt + options
  1825.           if str_length then
  1826.             onfound str_length
  1827.             search_string = new_string
  1828.           else
  1829.             say  new_string + " not found"  'b'
  1830.             if new_char then
  1831.               popcursor
  1832.             end
  1833.             onfound (sizeof search_string)
  1834.           end
  1835.         end
  1836.  
  1837.       until done
  1838.     end
  1839.  
  1840.  
  1841.     // find occurrences search
  1842.     function  findo (string_and_opt)
  1843.  
  1844.       var search_string
  1845.       var options
  1846.       var o
  1847.  
  1848.       n = splitstr '' string_and_opt
  1849.                    ref search_string  ref options  ref o
  1850.  
  1851.       // initialize search options
  1852.       if n >= 2 then
  1853.         if n > 2 then
  1854.           options = o
  1855.         end
  1856.       else
  1857.         options = _SearchOpt
  1858.       end
  1859.       if pos 'g' options then
  1860.         options = sub 'g' '' options
  1861.       end
  1862.       options = options + '*'
  1863.  
  1864.       // do the search
  1865.       buffer = createbuf
  1866.       ovltext "≡≡≡≡≡≡ Select this line to edit occurrences ≡≡≡≡≡≡"
  1867.       gotobuf (getprevbuf)
  1868.       pushcursor
  1869.       gotopos 1 1
  1870.       while find  search_string options  do
  1871.         addline  getrow + ": " + gettext  '' '' buffer
  1872.         col MAX_COL
  1873.       end
  1874.       popcursor
  1875.  
  1876.       // display occurrences
  1877.       if (getlines buffer) > 1 then
  1878.         bname = getbufname
  1879.         line = popup buffer
  1880.                  "Occurrences of '" + search_string + "' in "
  1881.                  + (getname bname) + " - " + ((getlines buffer) - 1) +
  1882.                  " lines"   getvidcols - 11 getvidrows - 8
  1883.         if line then
  1884.           if line [1] == '≡' then
  1885.             delline 1 1 buffer
  1886.             setbufname (qualify "TEMP.TXT" bname) buffer
  1887.             openbuf buffer
  1888.           else
  1889.             destroybuf buffer
  1890.             gotopos 1 line [1 : (pos ':' line) - 1]
  1891.             onfound (find search_string  options + '*')
  1892.           end
  1893.         end
  1894.       else
  1895.         destroybuf buffer
  1896.         display
  1897.         say  "'" + string_and_opt + "' not found"  'b'
  1898.       end
  1899.     end
  1900.  
  1901.     // prompt to find occurrences
  1902.     function  askfindo
  1903.       search_str = ask "[string/birswx] Find occurrences of"  "_find"
  1904.       if search_str then
  1905.         findo search_str
  1906.         addhistory "_find" search_str
  1907.       end
  1908.     end
  1909.  
  1910.     // find all occurrences of last find string
  1911.     function  findlasto
  1912.       findo (gethiststr "_find")
  1913.     end
  1914.  
  1915.     // find matching character (){}[]<>
  1916.     function  gotomatch2
  1917.       if gotomatch "(){}[]<>" then
  1918.         onfound 1
  1919.       else
  1920.         say "Not found" 'b'
  1921.       end
  1922.     end
  1923.  
  1924.     // goto column
  1925.     function  col2 (column)
  1926.       case column [1]
  1927.         when '+'   right  column [2 : TO_END]
  1928.         when '-'   left   column [2 : TO_END]
  1929.         otherwise  col (if? column > MAX_COL MAX_COL column)
  1930.       end
  1931.       onfound
  1932.     end
  1933.  
  1934.     // goto line
  1935.     function  row2 (line)
  1936.       case line [1]
  1937.         when '+'   down line [2 : TO_END]
  1938.         when '-'   up   line [2 : TO_END]
  1939.         otherwise  row (if? line > getlines (getlines) line)
  1940.       end
  1941.       onfound
  1942.     end
  1943.  
  1944.     // goto line prompt
  1945.     function  askrow
  1946.       askx "Line number" "_line" "row2"
  1947.     end
  1948.  
  1949.     // goto column prompt
  1950.     function  askcol
  1951.       askx "Column Number" '' "col2"
  1952.     end
  1953.  
  1954.     // set a quick bookmark
  1955.     function  quickbook
  1956.       _bk = _bk + 1
  1957.       bookmark = "Book" + _bk
  1958.       setbook bookmark
  1959.       display
  1960.       say "Bookmark " + bookmark + " set"
  1961.     end
  1962.  
  1963.     // place a bookmark
  1964.     function  placebook (bookmark)
  1965.       if not bookmark then
  1966.         bookmark = ask "Bookmark Name" "_book"
  1967.       end
  1968.       if bookmark then
  1969.         setbook bookmark
  1970.         display
  1971.         say "Bookmark '" + bookmark + "' set"
  1972.       end
  1973.     end
  1974.  
  1975.  
  1976.     // Go to the compiler error on the current line of a compiler
  1977.     // error output file. This function recognizes compiler errors
  1978.     // of the form:
  1979.     //
  1980.     //   <text>  FILENAME.EXT  <text>  LINENUMBER  <text> : MESSAGE
  1981.     //
  1982.     // (implemented by using regular expression searching confined
  1983.     // to the current line)
  1984.  
  1985.     function  gotoerror
  1986.       pushcursor
  1987.       // filename charclass to use (max closure without the period)
  1988.       fileset = "[a-zA-Z0-9_\-/\\\\@~:^!#$%&`']#"
  1989.       file_ext =  fileset + '\\.' + fileset
  1990.       // find the filename
  1991.       length = find file_ext 'xgl*'
  1992.       if length then
  1993.         filename = gettext (getcol) length
  1994.         right length
  1995.         // find the line number
  1996.         length = find "[0-9]#" 'xl'
  1997.         if length then
  1998.           line = gettext (getcol) length
  1999.           // find the message
  2000.           if find ':' 'l' then
  2001.             message = gettext getcol + 1
  2002.             popcursor
  2003.             // open the file
  2004.             if open filename then
  2005.               row line
  2006.               col (getlinebeg)
  2007.               send "onfound"
  2008.               say  message + '  '
  2009.               return
  2010.             end
  2011.           end
  2012.         end
  2013.       end
  2014.       popcursor
  2015.       display
  2016.       say "Compiler message not recognized."
  2017.     end
  2018.  
  2019.  
  2020.     // backup a file and return the backup filename if sucessful
  2021.     function  backup (file)
  2022.       if locatefile file then
  2023.         dir = _BackupDir
  2024.         if dir then
  2025.           if (sizeof dir) > 3 and  dir [LAST_CHAR] == "\\" then
  2026.             dir = dir [1 : (sizeof dir) - 1]
  2027.           end
  2028.           createdir dir
  2029.           dir = qualify dir
  2030.           backup_file = if pos "*.*" dir then
  2031.                           qualify (getname file) dir
  2032.                         else
  2033.                           msgbox "Unable to create backup file!"
  2034.                                  "Warning!"
  2035.                           return 1
  2036.                         end
  2037.         else
  2038.           backup_file = forceext file _BackupExt
  2039.         end
  2040.  
  2041.         // delete the old backup file
  2042.         deletefile backup_file
  2043.  
  2044.         // attempt a rename
  2045.         if not renamefile file backup_file then
  2046.           // try copy if rename fails
  2047.           if (copyfile file backup_file) <= 0 then
  2048.             msgbox "File backup failed!" "Error"
  2049.             return 0
  2050.           end
  2051.         end
  2052.         return backup_file
  2053.       else
  2054.         return 1
  2055.       end
  2056.     end
  2057.  
  2058.     // save the current file to disk
  2059.     function  save (file options)
  2060.       var c1
  2061.       var c2
  2062.  
  2063.       // check for a truncated file
  2064.       if trunc? and
  2065.          not (icompare (popup "ok" "Truncated file - are you sure?") "Ok") then
  2066.         return
  2067.       end
  2068.  
  2069.       file = if file then
  2070.                qualify file (getbufname)
  2071.              else
  2072.                getbufname
  2073.              end
  2074.       if fileattr? file 'r' then
  2075.         say "Read Only!" 'b'
  2076.       else
  2077.         backup_file = 1
  2078.         if setting? 'B' then
  2079.           backup_file = backup file
  2080.         end
  2081.         if not backup_file then
  2082.           say "Backup failed" 'b'
  2083.         else
  2084.           send "onsave" file
  2085.  
  2086.           // get fold comments for the file (if any)
  2087.           send "oncomment" file ref c1 ref c2
  2088.           options = _SaveOpt + options
  2089.           if not savebuf file
  2090.                    (if? (pos 'e' options) 'e' + _TabWidth) + options  ''
  2091.                    (if not getbinarylen then hex2bin _LineDlm end) ''
  2092.                    (if? c1 c1 + _FoldSign) c2 then
  2093.  
  2094.             // restore the backup after save failure
  2095.             if backup_file <> 1 then
  2096.               if not renamefile backup_file file then
  2097.                 copyfile backup_file file
  2098.               end
  2099.             end
  2100.             msgbox "Save failed!  Check file path / file attributes / disk space"  "Error!" 'b'
  2101.             return 0
  2102.           else
  2103.             1
  2104.           end
  2105.         end
  2106.       end
  2107.     end
  2108.  
  2109.     // save-as prompt
  2110.     function  asksaveas (options)
  2111.       file = ask "Save " + (getname (getbufname)) + " as"  "_load"
  2112.       if file then
  2113.         file = qualify file (getbufname)
  2114.         addhistory "_load" file
  2115.         save file options
  2116.       end
  2117.     end
  2118.  
  2119.     // start, stop, or do autosave
  2120.     function  autosave (seconds)
  2121.       if not seconds then
  2122.         if bufchanged? then
  2123.           save
  2124.         end
  2125.       elseif seconds < 0 then
  2126.         destroytimer "asav"
  2127.       else
  2128.         setrepeat "asav" seconds * 1000  '' "autosave"
  2129.       end
  2130.     end
  2131.  
  2132.     // prompt for autosave interval in seconds
  2133.     function  askasave
  2134.       seconds = ask "Autosave interval in secs (-1=disable)"
  2135.       if seconds then
  2136.         autosave seconds
  2137.       end
  2138.     end
  2139.  
  2140.     // highlight all occurrences of the word at the cursor
  2141.     function  hiliteword
  2142.       sobj = send "onsyntax" (getbufname)
  2143.       if not sobj then
  2144.         setting 'X' DEFAULT
  2145.         sobj = "syndef"
  2146.       end
  2147.       if sobj then
  2148.         w = send "getword" "a-zA-Z_0-9?"
  2149.         if w then
  2150.           // create a color selection menu
  2151.           menu "hcolor"
  2152.             item " &None"           -1
  2153.             item " &Default"        -2
  2154.             item "-"
  2155.             item " &Black"          color white on black
  2156.             item " B&lue"           color yellow on blue
  2157.             item " &Green"          color white on green
  2158.             item " &Cyan"           color white on cyan
  2159.             item " &Red"            color white on red
  2160.             item " &Magenta"        color white on magenta
  2161.             item " Br&own"          color white on brown
  2162.             item " Gr&ay"           color white on gray
  2163.             item "-"
  2164.             item " Dar&kgray"       color white on darkgray
  2165.             item " Brightbl&ue"     color white on brightblue
  2166.             item " Brightgr&een"    color black on brightgreen
  2167.             item " Brig&htcyan"     color black on brightcyan
  2168.             item " Br&ightred"      color white on brightred
  2169.             item " Brightmagen&ta"  color white on brightmagenta
  2170.             item " &Yellow"         color black on yellow
  2171.             item " &White"          color black on white
  2172.           end
  2173.           setbufname "colorlist"
  2174.           hcolor = popup "hcolor" "select a color "
  2175.           // destroy the menu
  2176.           destroybuf "hcolor"
  2177.           if hcolor then
  2178.             if hcolor == -1 then
  2179.               unsetx w sobj
  2180.             else
  2181.               setxobj w (if? hcolor == -2 '' hcolor) sobj
  2182.             end
  2183.           end
  2184.           display
  2185.         end
  2186.       end
  2187.     end
  2188.  
  2189.     // live word wrap support
  2190.     function  livewrap
  2191.  
  2192.       if fold? then
  2193.         return
  2194.       end
  2195.  
  2196.       startcol = getlinebeg
  2197.       if getrow < getlines and (getlinelen  getrow + 1) then
  2198.         n = getlinebeg  getrow + 1
  2199.         startcol = if? n < startcol  n  startcol
  2200.       elseif not getlinelen or not (setting? 'A') then
  2201.         startcol = _LMargin
  2202.       end
  2203.  
  2204.       if getcol < startcol then
  2205.         startcol = getcol
  2206.       end
  2207.  
  2208.       if getlinelen then
  2209.         undobegin
  2210.         saved_char = getchar
  2211.         ovltext '■'
  2212.  
  2213.         // mark to the end of the paragraph
  2214.         pushcursor
  2215.         top = getrow
  2216.         while down and getlinelen do end
  2217.         if not getlinelen then
  2218.           up
  2219.         end
  2220.         bottom = getrow
  2221.         popcursor
  2222.  
  2223.         // reformat
  2224.         usemark 'T'
  2225.         markcolumn startcol _RMargin top bottom
  2226.         formatblock '' '' "kr"
  2227.         destroymark
  2228.         usemark
  2229.  
  2230.         // find the original cursor position
  2231.         col 1
  2232.         find '■' '*'
  2233.         ovltext (if? saved_char saved_char ' ')
  2234.  
  2235.         undoend
  2236.       end
  2237.     end
  2238.  
  2239.     // enter a character or string at the cursor, with support for:
  2240.     //   - match character
  2241.     //   - translate
  2242.     //   - standard word wrap
  2243.     //   - live word wrap
  2244.  
  2245.     function  write (write_str)
  2246.  
  2247.       // group together as one undoable operation
  2248.       undobegin
  2249.  
  2250.       // enter the character or string at the cursor and
  2251.       // advance the cursor
  2252.       writetext write_str
  2253.  
  2254.       // get the current window settings
  2255.       setting_str = getsettings
  2256.  
  2257.       // match character
  2258.       if pos 'M' setting_str then
  2259.         instext ( case write_str
  2260.                     when '"'  '"'
  2261.                     when '('  ')'
  2262.                     when '['  ']'
  2263.                     when '{'  '}'
  2264.                     otherwise ''
  2265.                   end )
  2266.       end
  2267.  
  2268.       // translate
  2269.       if pos 'T' setting_str then
  2270.  
  2271.         // delimited lookup?
  2272.         to_word_end = if? (posnot _TranCSet write_str) 2 1
  2273.  
  2274.         // get the last word typed
  2275.         word_str = getword _TranCSet (getcol - to_word_end)
  2276.         if word_str then
  2277.           lookup_str = word_str + (if? to_word_end == 2 '*')
  2278.  
  2279.           // lookup the word in the translate object
  2280.           value = lookup lookup_str _TranObj
  2281.  
  2282.           if value then
  2283.             // is it a function? ..then evaluate it
  2284.             if function? lookup_str _TranObj then
  2285.               eval value
  2286.  
  2287.             // otherwise replace the word
  2288.             else
  2289.               word_column = getcol - (sizeof word_str) - to_word_end + 1
  2290.               delchar (sizeof word_str) word_column
  2291.               instext value word_column
  2292.               col word_column + (sizeof value) + to_word_end - 1
  2293.             end
  2294.           end
  2295.         end
  2296.       end
  2297.  
  2298.       // check for word wrap and live wrap
  2299.       if getlinelen > _RMargin then
  2300.  
  2301.         // live word wrap
  2302.         if pos 'L' setting_str then
  2303.           livewrap
  2304.  
  2305.         // standard word wrap
  2306.         elseif (pos 'W' setting_str) and (not fold?) then
  2307.           column = getcol
  2308.           limit = _RMargin + 1
  2309.           if column > limit then
  2310.             if write_str <> ' ' then
  2311.               first_col = if? (setting? 'A') (getlinebeg) _LMargin
  2312.               split_col = pos ' ' (gettext 1 limit) 'r'
  2313.               split_col = if? split_col > first_col  split_col + 1  limit
  2314.               splitline split_col
  2315.               down
  2316.               markline '' '' 'T'
  2317.               shiftblock  first_col - 1 'T'
  2318.               destroymark 'T'
  2319.               col  column - split_col + first_col
  2320.             end
  2321.           end
  2322.         end
  2323.       end
  2324.  
  2325.       undoend
  2326.     end
  2327.  
  2328.     // enter a date/time stamp at the cursor
  2329.     function  timestamp
  2330.       write getdate + ' ' + gettime
  2331.     end
  2332.  
  2333.  
  2334. // ───────────────────────────────────────────────────────────────────
  2335. //  File Manager windows
  2336. // ───────────────────────────────────────────────────────────────────
  2337.  
  2338.   object  fmgr
  2339.  
  2340.     // return the file name for fmgr commands
  2341.     function  fname2
  2342.       if fmark? then
  2343.         "MARKED FILES"
  2344.       else
  2345.         getname (getffile)
  2346.       end
  2347.     end
  2348.  
  2349.     // error notification
  2350.     function  ferror (s)
  2351.       msgbox  s + " Failed"  "Error!" 'b'
  2352.     end
  2353.  
  2354.     // fmgr confirmation prompt
  2355.     function  fconfirm (confirm pstring func)
  2356.       if (icompare confirm 'n') or
  2357.          (icompare (popup "ok" pstring + ' ' + fname2 + '?') "ok") then
  2358.         fdomark func
  2359.         reopen
  2360.       end
  2361.     end
  2362.  
  2363.     // internal fopen
  2364.     function  fopn (file options)
  2365.       if file then
  2366.         openf file options
  2367.       else
  2368.         fdomark "fopn" options
  2369.       end
  2370.     end
  2371.  
  2372.     // fmgr open file(s) command
  2373.     function  fopen (options)
  2374.  
  2375.       var searchopt
  2376.  
  2377.       if pos '1' options then
  2378.         if shiftkey? then
  2379.           options = options + 'v'
  2380.         end
  2381.         scanstr = fscanstr
  2382.         openf '' options
  2383.  
  2384.         // find first occurrence for scan windows
  2385.         if scanstr then
  2386.           addhistory "_find" scanstr
  2387.           splitstr '' scanstr '' ref searchopt
  2388.           gotopos 1 (if? (pos 'r' searchopt) (getlines) 1)
  2389.           send "onfound" (search scanstr)
  2390.         end
  2391.  
  2392.       else
  2393.         fopn '' options
  2394.       end
  2395.     end
  2396.  
  2397.     // fmgr change file attributes command
  2398.     function  fattr (file attr)
  2399.       if file then
  2400.         chgfileattr file attr
  2401.       else
  2402.         attr = ask "New attributes [AHSR] for " + fname2
  2403.         if attr then
  2404.           fdomark "fattr" (if? attr <> ' ' attr)
  2405.           reopen
  2406.         end
  2407.       end
  2408.     end
  2409.  
  2410.     // fmgr delete file(s) command
  2411.     function  fdelete (file)
  2412.       if file then
  2413.         if pos "*.*" file then
  2414.           file = getpath file
  2415.         end
  2416.         if not deletefile file 'd' then
  2417.           ferror "Delete"
  2418.         end
  2419.       else
  2420.         fconfirm _ConDel "Delete" "fdelete"
  2421.       end
  2422.     end
  2423.  
  2424.     // fmgr touch file(s) command
  2425.     function  ftouch (file)
  2426.       if file then
  2427.         if not touchfile file then
  2428.           ferror "Touch"
  2429.         end
  2430.       else
  2431.         fconfirm _ConTch "Touch" "ftouch"
  2432.       end
  2433.     end
  2434.  
  2435.     // print a file or directory with the current printer settings
  2436.     function  printfile (file)
  2437.       if loadbuf file '' '' _FmgrOpt _TruncLength then
  2438.         print
  2439.         destroybuf
  2440.       end
  2441.     end
  2442.  
  2443.     // fmgr print file(s) command
  2444.     function  fprint (file)
  2445.       if file then
  2446.         if not printfile file then
  2447.           ferror "Print"
  2448.         end
  2449.       else
  2450.         fconfirm 'y' "Print" "fprint"
  2451.       end
  2452.     end
  2453.  
  2454.     // fmgr run file command
  2455.     function  frun (options)
  2456.       run (getffile) options
  2457.       reopen
  2458.     end
  2459.  
  2460.     // fmgr rename file command
  2461.     function  frename
  2462.       oldname = getffile
  2463.       newname = ask  "Rename " + (getname oldname) + " to"  "_load"
  2464.       if newname then
  2465.         if renamefile oldname (qualify newname (getbufname)) then
  2466.           reopen
  2467.         else
  2468.           ferror "Rename"
  2469.         end
  2470.       end
  2471.     end
  2472.  
  2473.     // fmgr copy (or move) file(s) command
  2474.     function  fcopy (source dest options)
  2475.       if source then
  2476.         if dir? dest then
  2477.           dest = qualify (getname source) dest
  2478.         end
  2479.         action = askrac dest
  2480.         if pos action "ra" 'i' then
  2481.           move? = options == 'm'
  2482.           say (if? move? "Mov" "Copy") + "ing " + source "..."
  2483.           if not move? or (icompare action 'a') or not (renamefile source dest) then
  2484.             if not copyfile source dest (if? (icompare action 'a') 'a') then
  2485.               ferror (if? move? "Move" "Copy")
  2486.               fdobrk
  2487.             else
  2488.               if move? then
  2489.                 deletefile source
  2490.               end
  2491.             end
  2492.           end
  2493.         end
  2494.       else
  2495.         if fmark? then
  2496.           dir_dest = qualify (getffile)
  2497.           if not dir? dir_dest then
  2498.             dir_dest = ''
  2499.           end
  2500.         end
  2501.         dest = ask (if? options == 'm' "Move " "Copy ") + fname2 + " to"
  2502.                    "_load" dir_dest
  2503.         if dest then
  2504.           fdomark "fcopy" (qualify dest (getbufname)) options
  2505.           reopen
  2506.         end
  2507.       end
  2508.     end
  2509.  
  2510.     // fmgr move file(s) command
  2511.     function  fmove
  2512.       fcopy '' '' 'm'
  2513.     end
  2514.  
  2515.     // fmgr create new directory command
  2516.     function  fmkdir
  2517.       dir = ask "New directory name" "_load"
  2518.       if dir then
  2519.         if createdir (qualify dir (getbufname)) then
  2520.           reopen
  2521.         else
  2522.           ferror "Create directory"
  2523.         end
  2524.       end
  2525.     end
  2526.  
  2527.  
  2528. // ───────────────────────────────────────────────────────────────────
  2529. //  On-Event functions called by the editor
  2530. // ───────────────────────────────────────────────────────────────────
  2531.  
  2532.   // edit windows & file manager windows only
  2533.   object  edit_fmgr
  2534.  
  2535.     // called while loading files
  2536.     function  onloading (lines)
  2537.       say (if? lines  "Loading [" + lines + "]..."  getbufname)
  2538.     end
  2539.  
  2540.     // called while saving files
  2541.     function  onsaving (lines)
  2542.       say (if? lines  "Saving [" + lines + "]..."  getbufname)
  2543.     end
  2544.  
  2545.     // called while printing files
  2546.     function  onprinting (lines)
  2547.       say (if? lines  "Printing [" + lines + "]... <ctrl break> to stop "
  2548.            getbufname)
  2549.     end
  2550.  
  2551.     // called while scanning files
  2552.     function  onscanning (file found)
  2553.  
  2554.       // create scan progress window
  2555.       if not window? 'scan' then
  2556.  
  2557.         createwindow 'scan'
  2558.         setwinobj
  2559.         setframe ">b"
  2560.         setcolor  border_color   color white on gray
  2561.         setcolor  text_color     color black on gray
  2562.         settitle "Scanning" 'c'
  2563.         setborder "1i"
  2564.         setshadow 2 1
  2565.  
  2566.         // center the window
  2567.         width = (sizeof (getpath file)) + 24
  2568.         height = 16
  2569.         ox = (getvidcols - width) / 2
  2570.         oy = (getvidrows - height) / 2
  2571.         sizewindow ox oy ox + width oy + height "ad"
  2572.         writestr   file + "..."
  2573.  
  2574.       elseif found then
  2575.         writestr " FOUND" (color brightgreen on gray) (getcoord 'x1') - 7
  2576.  
  2577.       elseif file then
  2578.         writeline
  2579.         writestr   file + "..."
  2580.  
  2581.       else
  2582.         destroywindow
  2583.       end
  2584.  
  2585.       display
  2586.     end
  2587.  
  2588.     // called while compiling files
  2589.     function  oncompiling (file lines)
  2590.       say (if? lines  "Compiling " + file + " [" + lines + "]..."  getbufname)
  2591.     end
  2592.  
  2593.  
  2594.   // edit windows only
  2595.   object  edit
  2596.  
  2597.     // called after a file is opened and before it's displayed
  2598.     function  onopen
  2599.  
  2600.       // set window event object
  2601.       setwinobj "edit"
  2602.  
  2603.       // default window settings (if not remembered by open)
  2604.       if not getsettings then
  2605.         setting _DefaultSet ON
  2606.       end
  2607.  
  2608.       // check for file truncation
  2609.       if trunc? then
  2610.         display
  2611.         say "File Truncated!" 'b'
  2612.       end
  2613.     end
  2614.  
  2615.     // called immediately before a file is saved
  2616.     //function  onsave (file) then
  2617.     //end
  2618.  
  2619.     // called when switching to a file
  2620.     //function  onfocus
  2621.     //end
  2622.  
  2623.     // called when closing a file
  2624.     //function  onclose
  2625.     //end
  2626.  
  2627.     // called after a search to change the window view and
  2628.     // optionally highlight a string
  2629.     function  onfound (stringlength)
  2630.  
  2631.       // check if the cursor is outside the window view
  2632.       if getcol < getviewleft then
  2633.         if getcol < getviewcols then
  2634.           rollcol -getviewleft
  2635.         else
  2636.           adjustcol 3
  2637.         end
  2638.       elseif getcol + stringlength >= getviewright then
  2639.         adjustcol
  2640.       end
  2641.  
  2642.       if getrow > getviewbot then
  2643.         adjustrow 3
  2644.       elseif getrow < getviewtop then
  2645.         adjustrow
  2646.       end
  2647.       display
  2648.  
  2649.       // highlight a string if stringlength is specified
  2650.       if stringlength then
  2651.         hilite stringlength 1 (getpalette (if? (inmark?) 9 8))
  2652.       end
  2653.     end
  2654.  
  2655.  
  2656.   object  fmgr
  2657.  
  2658.     // called after a fmgr window is opened and before it's displayed
  2659.     function  onopen
  2660.  
  2661.       // set the window event object
  2662.       setwinobj "fmgr"
  2663.  
  2664.       // check for include picklist
  2665.       if ftype? 'i' then
  2666.         display
  2667.         say "Select file to insert"
  2668.       end
  2669.     end
  2670.  
  2671.  
  2672.   // all windows
  2673.   object  a
  2674.  
  2675.     // called when sounding an alarm
  2676.     // (allows you to customize the alarm sound)
  2677.     function  onalarm
  2678.       beep 750 70
  2679.     end
  2680.  
  2681.     // get default comments for a filename (c1, c2 passed by reference)
  2682.     // (associates a filename with comment symbols)
  2683.     function  oncomment (file c1 c2)
  2684.       case getext (upcase file)
  2685.         when ".C", ".AML", ".CPP", ".H"   c1 = "//"
  2686.         when ".ASM"                       c1 = ';'
  2687.         when ".PAS"                       c1 = '{'   c2 = '}'
  2688.         otherwise                         c1 = '>'
  2689.       end
  2690.     end
  2691.  
  2692.  
  2693.     // called when entering the editor before any windows are open.
  2694.     // DOS command-line filespecs are passed to this function
  2695.     function  onentry
  2696.  
  2697.       // save the DOS entry path
  2698.       _cp = getcurrpath
  2699.  
  2700.       // open prompt and window history
  2701.       if _SaveHistory == 'y' then
  2702.         openhistory (bootpath "history.dat")
  2703.       end
  2704.  
  2705.       // process command-line parameters passed to the editor
  2706.       param_num = 1
  2707.       parameter = arg 1
  2708.  
  2709.       while parameter do
  2710.  
  2711.         // check for command line options
  2712.         if parameter [1:2] == "-e"  then
  2713.           queue parameter [3 : TO_END]
  2714.  
  2715.         // open files/directories
  2716.         else
  2717.           open parameter
  2718.         end
  2719.  
  2720.         // next command line parm
  2721.         param_num = param_num + 1
  2722.         parameter = arg param_num
  2723.       end
  2724.  
  2725.       // still no windows open? then do bootoptions...
  2726.       if not getcurrwin then
  2727.         case _BootOpt
  2728.           when 'd'  restoredesk
  2729.           when 'f'  open '.'
  2730.           when 'n'  opennew
  2731.           otherwise
  2732.             filespec = ask "File or Directory" "_load"
  2733.             if filespec then
  2734.               open filespec
  2735.             else
  2736.               halt
  2737.             end
  2738.         end
  2739.       end
  2740.  
  2741.       // initialize the mouse
  2742.       if _Mouse == 'y' then
  2743.         if openmouse _MouseOpt then
  2744.           mousepos  15999 + getvidcols  15999 + getvidrows
  2745.           y_sens = _MouSenY
  2746.           if (getos 'v') > 9 then
  2747.             mousesense (_MouSenX * 5) / 8  (y_sens * 5) / 8  _MouDST
  2748.           else
  2749.             mousesense _MouSenX y_sens _MouDST
  2750.           end
  2751.         end
  2752.       end
  2753.  
  2754.       // open key macros if configured
  2755.       if _SaveMac == 'y' then
  2756.         openkey (bootpath "a.mac")
  2757.       end
  2758.  
  2759.       // set autosave timer
  2760.       send "autosave" _AutoSave
  2761.     end
  2762.  
  2763.  
  2764.     // called when exiting the editor after all windows are closed
  2765.     function  onexit
  2766.  
  2767.       // open prompt on non-global exit (if configured)
  2768.       if not __G then
  2769.         if _ExitOpen == 'y' then
  2770.           filespec = ask "File or Directory" "_load"
  2771.           if filespec then
  2772.             open filespec
  2773.           end
  2774.         end
  2775.       end
  2776.  
  2777.       // final exit if no windows open
  2778.       if not getcurrwin then
  2779.  
  2780.         // save prompt and window history
  2781.         if _SaveHistory == 'y' then
  2782.           savehistory (bootpath "history.dat")
  2783.         end
  2784.  
  2785.         // save key macros if configured
  2786.         if _SaveMac == 'y' then
  2787.           // check if record occurred
  2788.           if lookup "kd" "mon" then
  2789.             savekey (bootpath "a.mac")
  2790.           end
  2791.         end
  2792.  
  2793.         // restore entry path saved in onentry
  2794.         currpath _cp
  2795.  
  2796.         closemouse
  2797.         halt
  2798.       end
  2799.     end
  2800.  
  2801.